// Test behaviour of the ADTS.

#include <cstdio>
#include "adts/string.hpp"
#include "adts/vector.hpp"
#include "adts/map.hpp"
#include "adts/set.hpp"

using namespace Ripe;
using std::printf;

int main()
{
  // Test behaviour of strings
  {
    String s = "Hello world!\n";
    String b = s;  
    s = "Goodbye world!\n";
    printf(b.c_str);
    printf(s.c_str);
  }

  // Test behaviour of vector  
  Vector<int> v;
  for (int i = 0; i < 4096; i++){
    v.append(i);
  }
  if (v.size != 4096) return 1;
  for (int i = 0; i < 4090; i++){
    v.pop();
  }
  if (v.size != 6) return 1;
  v.clear();
  if (v.size != 0) return 1;
 
  // Test behaviour of maps
  Map<uint32_t, uint32_t> map;
  
  for (uint32_t i = 0; i < 1000; i++){
    map.set(i, i*i);
  }
  map.print();
  
  // Test behaviour of map iterator
  Map<uint32_t, uint32_t> map2;
  
  for (uint32_t i = 1; i <= 10; i++){
    map2.set(i, 2*i);
  }
  uint32_t sum1 = 0, sum2 = 0;
  MapIterator<uint32_t, uint32_t> iter(&map2);
  while (iter.has_more()){
    uint32_t key, value;
    iter.get(&key, &value);
    sum1 += key; sum2 += value;
  }
  if (sum1 != 55) return 1;
  if (sum2 != 110) return 1;

  // Test behaviour of sets
  Set<uint32_t> set;
  
  for (uint32_t i = 0; i < 1000; i++){
    set.set(i);
  }
  
  for (uint32_t i = 0; i < 1000; i++){
    if (not set.has(i)) return 1;
  }
  if (set.has(1001)) return 1;
  
  uint32_t x = set.get(500);
  if (x != 500) return 1;
  
  printf("All ADTS correct!\n");
  
  // Test behaviour of set iterator
  Set<uint32_t> set3;
  for (uint32_t i = 1; i <= 10; i++){
    set3.set(i);
  }
  
  sum1 = 0;
  SetIterator<uint32_t> iter2(&set3);
  while (iter2.has_more()){
    sum1 += iter2.get();
  }
  if (sum1 != 55) return 1;
  
  // Test behaviour of sets and strings
  Set<const char*> set2;
  
  set2.set("hello");
  set2.set("world");
  if (not set2.has("hello")) return 1;
  if (not set2.has("world")) return 1;
  
  return 0;
}
